package org.liujing.jsw.client.ui;

import com.google.gwt.user.client.ui.*;
import org.liujing.jsw.client.ui.plaf.*;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.*;
import java.io.Serializable;

public class Box extends Container {


    public Box(int axis) {
	super();
	super.setLayout(new BoxLayout(this, axis));
    }

    /**
     * Creates a <code>Box</code> that displays its components
     * from left to right. If you want a <code>Box</code> that
     * respects the component orientation you should create the
     * <code>Box</code> using the constructor and pass in
     * <code>BoxLayout.LINE_AXIS</code>, eg:
     * <pre>
     *   Box lineBox = new Box(BoxLayout.LINE_AXIS);
     * </pre>
     *
     * @return the box
     */
    public static Box createHorizontalBox() {
	return new Box(BoxLayout.X_AXIS);
    }

    /**
     * Creates a <code>Box</code> that displays its components
     * from top to bottom. If you want a <code>Box</code> that
     * respects the component orientation you should create the
     * <code>Box</code> using the constructor and pass in
     * <code>BoxLayout.PAGE_AXIS</code>, eg:
     * <pre>
     *   Box lineBox = new Box(BoxLayout.PAGE_AXIS);
     * </pre>
     *
     * @return the box
     */
    public static Box createVerticalBox() {
	return new Box(BoxLayout.Y_AXIS);
    }

    /**
     * Creates an invisible component that's always the specified size.
     * <!-- WHEN WOULD YOU USE THIS AS OPPOSED TO A STRUT? -->
     *
     * @param d the dimensions of the invisible component
     * @return the component
     * @see #createGlue
     * @see #createHorizontalStrut
     * @see #createVerticalStrut
     */
    public static JComponent createRigidArea(Dimension d) {
	return new Filler(d, d, d);
    }

    /**
     * Creates an invisible, fixed-width component.
     * In a horizontal box, 
     * you typically use this method 
     * to force a certain amount of space between two components.
     * In a vertical box,
     * you might use this method 
     * to force the box to be at least the specified width.
     * The invisible component has no height
     * unless excess space is available,
     * in which case it takes its share of available space,
     * just like any other component that has no maximum height.
     *
     * @param width the width of the invisible component, in pixels >= 0
     * @return the component
     * @see #createVerticalStrut
     * @see #createGlue
     * @see #createRigidArea
     */
    public static JComponent createHorizontalStrut(int width) {
	return new Filler(new Dimension(width,0), new Dimension(width,0), 
			  new Dimension(width, Short.MAX_VALUE));
    }

    /**
     * Creates an invisible, fixed-height component.
     * In a vertical box, 
     * you typically use this method
     * to force a certain amount of space between two components.
     * In a horizontal box,
     * you might use this method 
     * to force the box to be at least the specified height.
     * The invisible component has no width
     * unless excess space is available,
     * in which case it takes its share of available space,
     * just like any other component that has no maximum width.
     *
     * @param height the height of the invisible component, in pixels >= 0
     * @return the component
     * @see #createHorizontalStrut
     * @see #createGlue
     * @see #createRigidArea
     */
    public static JComponent createVerticalStrut(int height) {
	return new Filler(new Dimension(0,height), new Dimension(0,height), 
			  new Dimension(Short.MAX_VALUE, height));
    }

    /**
     * Creates an invisible "glue" component 
     * that can be useful in a Box
     * whose visible components have a maximum width
     * (for a horizontal box)
     * or height (for a vertical box).
     * You can think of the glue component
     * as being a gooey substance
     * that expands as much as necessary
     * to fill the space between its neighboring components.
     *
     * <p>
     *
     * For example, suppose you have
     * a horizontal box that contains two fixed-size components.
     * If the box gets extra space,
     * the fixed-size components won't become larger,
    * so where does the extra space go?
     * Without glue,
     * the extra space goes to the right of the second component.
     * If you put glue between the fixed-size components,
     * then the extra space goes there.
     * If you put glue before the first fixed-size component,
     * the extra space goes there,
     * and the fixed-size components are shoved against the right
     * edge of the box.
     * If you put glue before the first fixed-size component
     * and after the second fixed-size component,
     * the fixed-size components are centered in the box.
     *
     * <p>
     *
     * To use glue,
     * call <code>Box.createGlue</code>
     * and add the returned component to a container.
     * The glue component has no minimum or preferred size,
     * so it takes no space unless excess space is available.
     * If excess space is available, 
     * then the glue component takes its share of available
     * horizontal or vertical space,
     * just like any other component that has no maximum width or height.
     *
     * @return the component
     */
    public static JComponent createGlue() {
	return new Filler(new Dimension(0,0), new Dimension(0,0), 
			  new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
    }

    /**
     * Creates a horizontal glue component.
     *
     * @return the component
     */
    public static JComponent createHorizontalGlue() {
	return new Filler(new Dimension(0,0), new Dimension(0,0), 
			  new Dimension(Short.MAX_VALUE, 0));
    }

    /**
     * Creates a vertical glue component.
     *
     * @return the component
     */
    public static JComponent createVerticalGlue() {
	return new Filler(new Dimension(0,0), new Dimension(0,0), 
			  new Dimension(0, Short.MAX_VALUE));
    }

    /**
     * Throws an AWTError, since a Box can use only a BoxLayout.
     *
     * @param l the layout manager to use
     */
    public void setLayout(LayoutManager l) {
    	throw new Error("Illegal request");
    }

    

    /**
     * An implementation of a lightweight component that participates in
     * layout but has no view.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     */
    public static class Filler extends JComponent {

	/**
	 * Constructor to create shape with the given size ranges.
	 *
	 * @param min   Minimum size
	 * @param pref  Preferred size
	 * @param max   Maximum size
	 */
        public Filler(Dimension min, Dimension pref, Dimension max) {
            setMinimumSize(min);
            setPreferredSize(pref);
            setMaximumSize(max);
        }

	/**
	 * Change the size requests for this shape.  An invalidate() is
	 * propagated upward as a result so that layout will eventually
	 * happen with using the new sizes.
	 *
	 * @param min   Value to return for getMinimumSize
	 * @param pref  Value to return for getPreferredSize
	 * @param max   Value to return for getMaximumSize
	 */
        public void changeShape(Dimension min, Dimension pref, Dimension max) {
            setMinimumSize(min);
            setPreferredSize(pref);
            setMaximumSize(max);
            revalidate();
        }
	}
    
}
